package nautilus.moneykeeper.fragment;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import nautilus.moneykeeper.MainBaseSlidingActvity;
import nautilus.moneykeeper.R;
import nautilus.moneykeeper.adapter.SpinnerNamedAdapter;
import nautilus.moneykeeper.dao.AccountDAO;
import nautilus.moneykeeper.dto.Account;
import nautilus.moneykeeper.dto.Category;
import nautilus.moneykeeper.dto.CurrencyUnit;
import nautilus.moneykeeper.dto.PaymentMethod;
import nautilus.moneykeeper.dto.Transaction;
import nautilus.moneykeeper.fragment.AbstractMainContentFragment;
import nautilus.moneykeeper.system.Constant;
import nautilus.moneykeeper.system.Device;
import nautilus.moneykeeper.utilities.ImageUtility;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.Toast;

public class TranFragment extends AbstractMainContentFragment implements OnCheckedChangeListener{
	//private static final String TAG = "TransActivity";
	private Spinner spinnerAccount, spinnerCategory, spinnerUnit, spinnerPaymentMethod;
	private RadioButton rdIncome, rdOutcome;
	private EditText txtAmount, txtDescription;
	private SpinnerNamedAdapter<Account> dataAdapterAc;
	private SpinnerNamedAdapter<Category> adapterCat;
	private SpinnerNamedAdapter<CurrencyUnit> adapterUnit;
	private SpinnerNamedAdapter<PaymentMethod> adapterPM;
	private ImageView transactionImage;
	
	private Account selectedAccount;
	private Category selectedCategory;
	private CurrencyUnit selectedUnit;
	private PaymentMethod selectedPaymentMethod;
	private String _pictureFile = null;
	
	private ArrayList<Account> lstAccs = null;
	private ArrayList<Category> lstCat = null;
	private ArrayList<PaymentMethod> lstPM = null;
	private ArrayList<CurrencyUnit> lstUnit = null;
	private Transaction _thisTransaction = null;
	
	private Handler _handler = new Handler(new Handler.Callback() {
		
		@Override
		public boolean handleMessage(Message msg) {
			switch(msg.what){
				case Constant.MSG_LOAD_DATA_DONE:
					bindData();
					break;
					
				case Constant.MSG_LOAD_DATA_ERROR:
					break;
					
				case Constant.MSG_DATA_SAVED_OK:
					break;
			}
			return false;
		}
	});
	
	@SuppressWarnings("unchecked")
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedState){
		View view = inflater.inflate(R.layout.trans, parent, false);
		spinnerAccount = (Spinner)view.findViewById(R.id.spinnerAccount);
		spinnerAccount.setOnItemSelectedListener(new OnItemSelectedListener(){

			@Override
			public void onItemSelected(AdapterView<?> adapter, View arg1, int arg2, long arg3) {
				selectedAccount = (Account)adapter.getSelectedItem();
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {	
			}			
		});
		
		spinnerCategory = (Spinner)view.findViewById(R.id.spinnerCategory);
		spinnerCategory.setOnItemSelectedListener(new OnItemSelectedListener(){

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				selectedCategory = (Category) arg0.getSelectedItem();
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
			}
		});

		spinnerUnit = (Spinner)view.findViewById(R.id.spinnerUnit);
		spinnerUnit.setOnItemSelectedListener(new OnItemSelectedListener(){

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				selectedUnit = (CurrencyUnit)arg0.getSelectedItem();
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {	
			}			
		});

		spinnerPaymentMethod = (Spinner)view.findViewById(R.id.spinnerPaymentMethod);
		spinnerPaymentMethod.setOnItemSelectedListener(new OnItemSelectedListener(){

			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				selectedPaymentMethod = (PaymentMethod)arg0.getSelectedItem();
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {	
			}			
		});
		
		txtAmount = (EditText)view.findViewById(R.id.txtAmount);
		txtDescription = (EditText)view.findViewById(R.id.txtDescription);
		rdIncome = (RadioButton)view.findViewById(R.id.tran_rd_income);
		rdIncome.setOnCheckedChangeListener(this);
		rdOutcome = (RadioButton)view.findViewById(R.id.tran_rd_outcome);
		rdOutcome.setOnCheckedChangeListener(this);
		
		transactionImage = (ImageView)view.findViewById(R.id.transaction_image);

		if(savedState!= null){
			lstAccs = (ArrayList<Account>) savedState.getSerializable("list_account");
			lstCat =  (ArrayList<Category>) savedState.getSerializable("list_catagory");
			lstPM =  (ArrayList<PaymentMethod>) savedState.getSerializable("list_method");
			lstUnit =  (ArrayList<CurrencyUnit>) savedState.getSerializable("list_unit");
			selectedAccount = (Account) savedState.getSerializable(Constant.EXTRA_ACCOUNT);
			if(dataAdapterAc == null){
				dataAdapterAc = new SpinnerNamedAdapter<Account>(getActivity(), lstAccs);
				adapterCat = new SpinnerNamedAdapter<Category>(getActivity(), lstCat);
				adapterPM = new SpinnerNamedAdapter<PaymentMethod>(getActivity(), lstPM);
				adapterUnit = new SpinnerNamedAdapter<CurrencyUnit>(getActivity(), lstUnit);
				spinnerUnit.setAdapter(adapterUnit);
				spinnerPaymentMethod.setAdapter(adapterPM);
				spinnerCategory.setAdapter(adapterCat);
				spinnerAccount.setAdapter(dataAdapterAc);
			}else{
				adapterUnit.refreshData(lstUnit);
				adapterCat.refreshData(lstCat);
				adapterPM.refreshData(lstPM);
			}
			selectedCategory = (Category)savedState.getSerializable("selected_category");
			selectedPaymentMethod = (PaymentMethod)savedState.getSerializable("selected_method");
			selectedUnit = (CurrencyUnit)savedState.getSerializable("selected_unit");
			txtAmount.setText(savedState.getString("amount"));
			txtDescription.setText(savedState.getString("description"));
			
			boolean d = savedState.getBoolean("direction");
			rdIncome.setChecked(d);
			rdOutcome.setChecked(!d);
			
			_thisTransaction = (Transaction) savedState.getSerializable(Constant.EXTRA_TRANSACTION);
			_pictureFile = savedState.getString("file_name");
			if(_pictureFile!=null && _pictureFile.length()>0){
				File dir = new File(Constant.PICTURE_STORE);
				File picFile = new File(dir.getAbsolutePath() +"/"+ _pictureFile);
				DisplayMetrics displaymetrics = new DisplayMetrics();
				getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
				float w = displaymetrics.widthPixels * 0.7f;
			    Bitmap bm = ImageUtility.decodeSampledBitmapFromUri(picFile.getAbsolutePath(), (int)w, (int)w);
				transactionImage.setImageBitmap(bm);
			}
			return view;
		}
		
		selectedAccount = (Account)getArguments().getSerializable(Constant.EXTRA_ACCOUNT);
		//_thisTransaction = (Transaction)getArguments().getSerializable(Constant.EXTRA_TRANSACTION);
		loadData();
		return view;
	}
	
	public void onSaveInstanceState(Bundle outState){
		super.onSaveInstanceState(outState);
		
		outState.putString(Constant.CLASS_NAME, getClass().getName());
		
		if(_pictureFile != null)
			outState.putSerializable("file_name", _pictureFile);
		
		if(lstAccs != null)
			outState.putSerializable("list_account", lstAccs);
		
		if(lstCat != null)
			outState.putSerializable("list_catagory", lstCat);
		
		if(lstPM != null)
			outState.putSerializable("list_method", lstPM);
		
		if(lstUnit != null)
			outState.putSerializable("list_unit", lstUnit);
		
		if(selectedAccount != null)
			outState.putSerializable(Constant.EXTRA_ACCOUNT, selectedAccount);
		
		if(selectedCategory != null)
			outState.putSerializable("selected_category", selectedCategory);
		
		if(selectedPaymentMethod != null)
			outState.putSerializable("selected_method", selectedPaymentMethod);
		
		if(selectedUnit != null)
			outState.putSerializable("selected_unit", selectedUnit);
		
		if(_thisTransaction != null)
			outState.putSerializable(Constant.EXTRA_TRANSACTION, _thisTransaction);
		
		if(txtAmount.getText().toString().length()>0)
			outState.putString("amount", txtAmount.getText().toString());
		
		if(txtDescription.getText().toString().length()>0)
			outState.putString("description", txtDescription.getText().toString());
		
		outState.putBoolean("direction", rdIncome.isChecked());
	}
	
	
	private void loadData(){
		Thread thread = new Thread(new Runnable(){
			@Override
			public void run(){
				AccountDAO accountDao = new AccountDAO(getActivity());
				lstAccs = accountDao.getAllAccounts();
				lstCat = accountDao.getAllCategories();
				lstPM = accountDao.getAllPaymentMethods();
				lstUnit = accountDao.getAllCurrencyUnits();
				accountDao.close();
				_handler.sendEmptyMessage(Constant.MSG_LOAD_DATA_DONE);
			}}
		);
		thread.start();
	}
	
	private void bindData(){
		int i;
		if(dataAdapterAc == null){
			dataAdapterAc = new SpinnerNamedAdapter<Account>(getActivity(), lstAccs);
			adapterCat = new SpinnerNamedAdapter<Category>(getActivity(), lstCat);
			adapterPM = new SpinnerNamedAdapter<PaymentMethod>(getActivity(), lstPM);
			adapterUnit = new SpinnerNamedAdapter<CurrencyUnit>(getActivity(), lstUnit);
			spinnerUnit.setAdapter(adapterUnit);
			spinnerPaymentMethod.setAdapter(adapterPM);
			spinnerCategory.setAdapter(adapterCat);
			spinnerAccount.setAdapter(dataAdapterAc);
		}else{
			adapterUnit.refreshData(lstUnit);
			adapterCat.refreshData(lstCat);
			adapterPM.refreshData(lstPM);
		}
		
		if(getArguments() != null){
			_thisTransaction = (Transaction) getArguments().getSerializable(Constant.EXTRA_TRANSACTION);
			if(_thisTransaction != null){
				for(i=0;i<adapterCat.getCount(); i++)
					if( ((Category) adapterCat.getItem(i)).getId() 
							== _thisTransaction.getCategory().getId()	){
						spinnerCategory.setSelection(i);
						break;
					}
				
				for(i=0;i<adapterPM.getCount(); i++)
					if( ((PaymentMethod) adapterPM.getItem(i)).getId() 
							== _thisTransaction.getPaymentMethod().getId()	){
						spinnerPaymentMethod.setSelection(i);
						break;
					}
				txtAmount.setText(_thisTransaction.getAmount()+"");
				txtDescription.setText(_thisTransaction.getDescription());
				
				rdIncome.setChecked(_thisTransaction.getType() == 1?true:false);
				rdOutcome.setChecked(_thisTransaction.getType() == 0?true:false);
				
				File dir = new File(Constant.PICTURE_STORE);
				File picFile = new File(dir.getAbsolutePath() +"/"+ _thisTransaction.getImage());
				
				DisplayMetrics displaymetrics = new DisplayMetrics();
				getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
				float w = displaymetrics.widthPixels * 0.7f;
				//android.util.Log.i("TranFragment", "resultCode: "+ resultCode +"( need: " + Activity.RESULT_OK +"); RequestCode: " + requestCode + "; picture width: " + w);
			    Bitmap bm = ImageUtility.decodeSampledBitmapFromUri(picFile.getAbsolutePath(), (int)w, (int)w);
				transactionImage.setImageBitmap(bm);
				transactionImage.postInvalidate();
			}
		}
	}
	
	private void onTakePhotoClicked(){
		Intent intentTakePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		File dir = new File(Constant.PICTURE_STORE);
		File picFile;
		if (!dir.exists()) {
			dir.mkdirs();
		}
		SimpleDateFormat format = new SimpleDateFormat("ddMMyyyyhhmmss");
		_pictureFile = "pic"+ format.format(new Date())+ ".jpg";
		picFile = new File(dir.getAbsolutePath() +"/"+ _pictureFile);
		intentTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(picFile));
		startActivityForResult(intentTakePhoto, Constant.REQUEST_TAKE_PICTURE);
	}
	
	private void onUpdateTransaction(){
		_thisTransaction.setAccount(selectedAccount);
		_thisTransaction.setCategory(selectedCategory);		
		_thisTransaction.setDatetime(new Date());
		_thisTransaction.setPaymentMethod(selectedPaymentMethod);
		_thisTransaction.setType(rdIncome.isChecked()?1:0);
		_thisTransaction.setAmount(Long.parseLong(txtAmount.getText().toString()));
		_thisTransaction.setDescription(txtDescription.getText().toString());
		_thisTransaction.setImage(_pictureFile==null?"":_pictureFile);
		AccountDAO dao = new AccountDAO(getActivity());
		dao.updateTransaction(_thisTransaction);
		dao.close();
	}
	
	private void onSaveClicked(){
		Transaction trans= new Transaction();
		trans.setAccount(selectedAccount);
		trans.setCategory(selectedCategory);
		trans.setDatetime(new Date());
		trans.setPaymentMethod(selectedPaymentMethod);
		trans.setType(rdIncome.isChecked()?1:0);
		trans.setAmount(Long.parseLong(txtAmount.getText().toString()));
		trans.setDescription(txtDescription.getText().toString());
		
		trans.setImage(_pictureFile==null?"":_pictureFile);
		
		AccountDAO dao = new AccountDAO(getActivity());
		long id = dao.addTransaction(trans);
		dao.close();
		
		if(id > 0)
			Toast.makeText(getActivity(), "Transaction saved.", Toast.LENGTH_LONG).show();
	}
	
	private boolean validateFormData(){
		String str = txtAmount.getText().toString();
		if(str.length()<=0){
			Toast.makeText(getActivity(), "Amount can not be blank.", Toast.LENGTH_LONG).show();
			txtAmount.requestFocus();
			return false;
		}
		return true;
	}

	@Override
	public void onClick(View v) {
		switch(v.getId()){
			case R.id.btn_menu_back:
				onBackPressed();
				break;
				
			case R.id.tran_btn_save:
				if(!validateFormData())
					return;
				if(_thisTransaction != null)
					onUpdateTransaction();
				else
					onSaveClicked();
				break;
			case R.id.btnTakePhoto:
				onTakePhotoClicked();
				break;
		}
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data){
		if( (resultCode == Activity.RESULT_OK) && (requestCode == Constant.REQUEST_TAKE_PICTURE )){
			DisplayMetrics displaymetrics = new DisplayMetrics();
			getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
			float w = displaymetrics.widthPixels * 0.7f;
			//android.util.Log.i("TranFragment", "resultCode: "+ resultCode +"( need: " + Activity.RESULT_OK +"); RequestCode: " + requestCode + "; picture width: " + w);
			File dir = new File(Constant.PICTURE_STORE);
			File picFile = new File(dir.getAbsolutePath() +"/"+ _pictureFile);
		    Bitmap bm = ImageUtility.decodeSampledBitmapFromUri(picFile.getAbsolutePath(), (int)w, (int)w);
			transactionImage.setImageBitmap(bm);
			transactionImage.postInvalidate();
		}
	}
	
	@Override
	public void onBackPressed(){
		Bundle args = new Bundle();
		args.putSerializable(Constant.EXTRA_ACCOUNT, selectedAccount);
		((MainBaseSlidingActvity)getActivity()).postBackPressed(args);
	}


	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		if(buttonView == rdIncome){
			
			return;
		}
		
		if(buttonView == rdOutcome){
			
		}
	}
}
